從 NodeSelector 的限制,到更靈活的三劍客
最近在管理 Kubernetes 時,我遇到一個很典型的問題:
剛開始,我用的都是最簡單的 NodeSelector 來解決調度問題:
nodeSelector:
disktype: ssd
只要給 Node 打上標籤,再讓 Pod 指定這個標籤,Pod 就會乖乖地排到符合條件的 Node 上。
但是,這種方法在實務上很快就遇到瓶頸:
這時,我才開始深入研究 Kubernetes 的調度三劍客:
Taints、Tolerations、Affinity。
想像 Kubernetes 集群是一間餐廳:
問題是:
這時就需要進階的規則:
Taint 是 Node 主動排斥 Pod 的方法。
它會在 Node 上貼一個「告示牌」,沒有符合條件的 Pod 就不能坐下。
格式:
kubectl taint nodes <node-name> key=value:Effect
三種 Effect:
範例:給 GPU 節點加上 Taint
kubectl taint nodes gpu-node gpu=true:NoSchedule
這代表這張「GPU 座位」貼上了告示牌:
只有持 GPU 證明的顧客可以坐
Toleration 是 Pod 上的通行證,用來容忍特定的 Taint。
有這張證明的 Pod,才能坐到被 Taint 限制的 Node。
範例:Pod 帶上 GPU 通行證
apiVersion: v1
kind: Pod
metadata:
name: gpu-pod
spec:
tolerations:
- key: "gpu"
operator: "Equal"
value: "true"
effect: "NoSchedule"
這就像顧客拿著「GPU 卡」,服務員會讓他坐在貼了「僅限 GPU」的桌子上。
Affinity 是 Pod 的座位偏好。
它可以控制 Pod 傾向去哪個 Node,或是跟哪些 Pod 在一起。
分成三種:
requiredDuringSchedulingIgnoredDuringExecution
) 與偏好 (preferredDuringSchedulingIgnoredDuringExecution
)範例:Node Affinity
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: disktype
operator: In
values:
- ssd
這表示顧客(Pod)必須坐在有 disktype=ssd
的桌子(Node)。
問題:開發人員不小心把非 GPU 工作丟到 GPU 節點上。
解法:
gpu=true:NoSchedule
問題:測試服務誤上生產節點。
解法:
env=prod:NoSchedule
問題:三個副本都排在同一台 Node,掛了就全掛。
解法:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- my-service
topologyKey: "kubernetes.io/hostname"
問題:Web Pod 與 Cache Pod 分開部署,性能下降。
解法:
機制 | 調度方向 | 用途 | 比喻 |
---|---|---|---|
Taints | Node → Pod | 排斥不符合的 Pod | 餐桌貼告示牌 |
Tolerations | Pod → Node | 允許坐有限制的桌子 | 顧客通行證 |
Affinity | Pod → Node/Pod | 偏好或要求位置 | 顧客座位喜好 |
NodeSelector 是調度的入門方法,但它像一條直線,缺乏彈性。
Taints / Tolerations / Affinity 則像餐廳的座位規則與顧客喜好,能讓資源利用率更高、服務更穩定。
當你下次遇到 Pod 排不上去,或資源被亂用的情況,不妨想想:
是不是該貼一張告示牌(Taint)、發一張通行證(Toleration)、或幫顧客安排更合適的座位(Affinity)?